package gotnames.web.st;

import gotnames.Pair;
import gotnames.dm.FindOrCreate;
import gotnames.dm.Group;
import gotnames.dm.KTrans;
import gotnames.dm.PersistedEntityValue;
import gotnames.dm.ProfilePicture;
import gotnames.dm.ProfilePictureData;
import gotnames.dm.User;
import gotnames.dm.User.Gender;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.apache.commons.io.IOUtils;

import com.medallia.spider.Task;
import com.medallia.tiny.Empty;
import com.medallia.tiny.Func;
import com.medallia.tiny.Funcs;

/**
 * Task used to create some test data; the values in {@link #PEOPLE} are movie
 * starts and their pictures are taken from IMDB.
 */
public class CreateTestDataTask extends Task {
	
	private static final String[][] PEOPLE = new String[][] {
		{ "Arnold", "Schwarzenegger", "m", "http://ia.media-imdb.com/images/M/MV5BMTI3MDc4NzUyMV5BMl5BanBnXkFtZTcwMTQyMTc5MQ@@._V1._SY314_CR18,0,214,314_.jpg" },
		{ "Michael", "Dudikoff", "m", "http://ia.media-imdb.com/images/M/MV5BMTQ4MTA1NDMyOV5BMl5BanBnXkFtZTcwNjgzMzA3Mg@@._V1._SY314_CR126,0,214,314_.jpg" },
		{ "Jean-Claude Van", "Damme", "m", "http://ia.media-imdb.com/images/M/MV5BMTA2OTE1Njg4NjVeQTJeQWpwZ15BbWU3MDAyNjU4MDM@._V1._SY314_CR20,0,214,314_.jpg" },
		{ "Dolph", "Lundgren", "m", "http://ia.media-imdb.com/images/M/MV5BMjE3MzIzNDMwMl5BMl5BanBnXkFtZTcwMDAzNDk1Mw@@._V1._SY314_CR128,0,214,314_.jpg" },
		{ "Steven", "Seagal", "m", "http://ia.media-imdb.com/images/M/MV5BMTczNTU4ODcyMV5BMl5BanBnXkFtZTYwMzkyMjA1._V1._SY314_CR8,0,214,314_.jpg" },
		{ "Bruce", "Willis", "m", "http://ia.media-imdb.com/images/M/MV5BMjA0MjMzMTE5OF5BMl5BanBnXkFtZTcwMzQ2ODE3Mw@@._V1._SY314_CR26,0,214,314_.jpg" },
		{ "Orlando", "Bloom", "m", "http://ia.media-imdb.com/images/M/MV5BMjE1MDkxMjQ3NV5BMl5BanBnXkFtZTcwMzQ3Mjc4MQ@@._V1._SY314_CR7,0,214,314_.jpg" },
		{ "Robert", "Duvall", "m", "http://ia.media-imdb.com/images/M/MV5BMjk1MjA2Mjc2MF5BMl5BanBnXkFtZTcwOTE4MTUwMg@@._V1._SY314_CR5,0,214,314_.jpg" },
		
		{ "Jodie", "Foster", "f", "http://ia.media-imdb.com/images/M/MV5BMTM3MjgyOTQwNF5BMl5BanBnXkFtZTcwMDczMzEwNA@@._V1._SY314_CR0,0,214,314_.jpg" },
		{ "Jennifer", "Aniston", "f", "http://ia.media-imdb.com/images/M/MV5BNjk1MjIxNjUxNF5BMl5BanBnXkFtZTcwODk2NzM4Mg@@._V1._SY314_CR2,0,214,314_.jpg" },
		{ "Jessica", "Alba", "f", "http://ia.media-imdb.com/images/M/MV5BODYxNzE4OTk5Nl5BMl5BanBnXkFtZTcwODYyMDYzMw@@._V1._SY314_CR11,0,214,314_.jpg" },
		{ "Halle", "Berry", "f", "http://ia.media-imdb.com/images/M/MV5BMjIxNzc5MDAzOV5BMl5BanBnXkFtZTcwMDUxMjMxMw@@._V1._SY314_CR9,0,214,314_.jpg" },
		{ "Angelina", "Jolie", "f", "http://ia.media-imdb.com/images/M/MV5BMjA3MjczNzU1OV5BMl5BanBnXkFtZTcwODM3OTc1Mg@@._V1._SY314_CR4,0,214,314_.jpg" },
		{ "Sandra", "Bullock", "f", "http://ia.media-imdb.com/images/M/MV5BMTI5NDY5NjU3NF5BMl5BanBnXkFtZTcwMzQ0MTMyMw@@._V1._SY314_CR0,0,214,314_.jpg" },
		{ "Hilary", "Swank", "f", "http://ia.media-imdb.com/images/M/MV5BMTM5NzQzNTU4NV5BMl5BanBnXkFtZTcwMDAyOTMwMw@@._V1._SY314_CR11,0,214,314_.jpg" },
		{ "Kate", "Hudson", "f", "http://ia.media-imdb.com/images/M/MV5BMTA1NTk0MjMyOTFeQTJeQWpwZ15BbWU3MDA4NzEzMTM@._V1._SY314_CR11,0,214,314_.jpg" }
	};
	
	PostAction action(User user, final PersistenceManager pm) {
		final String groupName = "Celebrity";
		
		// create the group
		PersistedEntityValue<Group> pe = new FindOrCreate<Group>(pm, Group.class) {
			@Override protected Object execute(Query query) {
				query.setFilter("name == fieldParam");
				query.declareParameters("String fieldParam");
				return query.execute(groupName);
			}
			@Override protected void setValues(Group x) {
				x.setName(groupName);
			}
		}.go();
		
		if (!pe.isNew())
			return rawStringUtf8("Group " + groupName + " already exists");
		
		final Long groupKey = pe.getEntityValue().getKey();
		
		final List<Pair<User, ProfilePictureData>> users = Funcs.map(Arrays.asList(PEOPLE), new Func<String[], Pair<User, ProfilePictureData>>() {
			private boolean first = true;
			@Override public Pair<User, ProfilePictureData> call(final String[] person) {
				return new KTrans<Pair<User, ProfilePictureData>>(pm) {
					@Override protected Pair<User, ProfilePictureData> call() {
						User u = User.newUser(groupKey);
						u.setFirstName(person[0]);
						u.setLastName(person[1]);
						u.setEmail(person[0].toLowerCase() + "@example.com");
						u.setGender(person[2].equals("m") ? Gender.MALE : Gender.FEMALE);
						
						if (first) {
							u.setAdmin(true);
							first = false;
						}

						try {
							URL url = new URL(person[3]);
							byte[] rawProfilePictureBytes = IOUtils.toByteArray(url.openStream());

							ProfilePictureData profilePicture = ProfilePictureData.getProfilePicture(rawProfilePictureBytes);
							u.setProfilePictureInfo(profilePicture);

							pm.makePersistent(u);

							return Pair.cons(u, profilePicture);

						} catch (MalformedURLException e) {
							throw new IllegalStateException(e);
						} catch (IOException e) {
							throw new IllegalStateException("while contacting " + person[2], e);
						}
					}
				}.go();
			}
		});
		
		for (final Pair<User, ProfilePictureData> u : users) {
			new KTrans.Void(pm) {
				@Override protected void run() {
					ProfilePicture.saveProfilePicture(u.first, pm, u.second);
				}
			}.go();
		}
		
		StringBuilder sb = Empty.sb();
		sb.append("OK; created " + users.size() + " users\n");
		for (Pair<User, ProfilePictureData> u : users) {
			sb.append(u.first.getFullName() + ": " + u.first.getAuthToken() + "\n");
		}
		
		return rawStringUtf8(sb.toString());
	}

}
